from urllib.parse import urlencode

from django.shortcuts import render

# Create your views here.
from rest_framework import status
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response

from rest_framework.views import APIView
from django.conf import settings
from rest_framework_jwt.settings import api_settings

from cart.utils import merge_cookie_to_reids
from oauth.serializers import QQRegisterSerializer
from .models import OAuthQQUser
from .utils import QQAuthonTool


class QQTokenView(GenericAPIView):
    """
    获取token
    """
    serializer_class = QQRegisterSerializer

    def get(self, request):
        # 1. 获取code值
        code = request.query_params.get('code')

        # 校验code值
        if not code:
            return Response({'message': '缺少参数'}, status.HTTP_400_BAD_REQUEST)

        # 创建工具类
        tool = QQAuthonTool()

        try:
            # 获取token
            access_token = tool.get_token_by_code(code)

            # 获取openid
            openid = tool.get_openid_by_token(access_token)
        except Exception:
            return Response({"message": "服务器出错"}, status.HTTP_503_SERVICE_UNAVAILABLE)

        try:
            qq_user = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 不存在就是第一次授权登录
            token = OAuthQQUser.generate_save_user_token(openid)
            return Response({'access_token': token})
        else:
            # 查询用户,生成登录token
            user = qq_user.user
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)

            response = Response({
                'token': token,
                'user_id': user.id,
                'username': user.username
            })
            response = merge_cookie_to_reids(request, response, user)
            return response

    def post(self, request):
        """
        绑定用户

        :param request:
        :return:
        """
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()

        # 生成已登录的token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        response = Response({
            'token': token,
            'user_id': user.id,
            'username': user.username
        })
        response = merge_cookie_to_reids(request, response, user)
        return response


class QQAuthUrlView(APIView):
    """
    /oauth/qq/statues/
    返回 qq登陆页面地址
    """

    def get(self, request):
        """
        1.获取qq登陆页面地址
        2.使用字典封装参数
        3.拼接地址家参数
        4.将地址返回
        :param request:
        :return:
        """

        # 获取state
        state = request.query_params.get('state')

        # 1.获取qq登陆页面地址
        base_url = 'https://graph.qq.com/oauth2.0/authorize?'

        # 2.使用字典封装参数
        # response_type     必须  授权类型，此值固定为“code”。
        # client_id         必须  申请QQ登录成功后，分配给应用的appid。
        # redirect_uri      必须  成功授权后的回调地址，必须是注册appid时填写的主域名下的地址，
        #                         建议设置为网站首页或网站的用户中心。注意需要将url进行URLEncode。
        # state             必须  client端的状态值。用于第三方应用防止CSRF攻击，成功授权后回调时会原样带回。
        #                        请务必严格按照流程检查用户与state参数状态的绑定。
        params = {
            "response_type": "code",
            "client_id": settings.QQ_APP_ID,
            "redirect_uri": settings.QQ_REDIRECT_URL,
            "state": state
        }

        # 3.拼接地址加参数
        # 对参数进行urlencode,然后拼接url
        auth_url = base_url + urlencode(params)

        # 4.将地址返回
        return Response({"auth_url": auth_url})
